#pragma once
#include "rtcp.h"

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <string>
#include <vector>

// RTP协议

/***************************************************************
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*****************************************************************/
#define RTPHEADSIZE 12
/**RTP 头结构**/
//使用位域
typedef struct {
    /** byte 0 **/
    unsigned char bit4CsrcLen : 4;   /** expect 0 **/
    unsigned char bit1Extension : 1; /** expect 1, see RTP_OP below **/
    unsigned char bit1Padding : 1;   /** expect 0 **/
    unsigned char bit1Version : 2;   /** expect 2 **/
    /** byte 1 **/
    unsigned char bit7PayLoadType : 7; /** RTP_PAYLOAD_RTSP **/
    unsigned char bit1Marker : 1;      /** expect 1 **/
    /** bytes 2,3 **/
    unsigned int u32SeqNum; /** RTP sequence number **/
    /** bytes 4-7 **/
    unsigned int u32TimeStamp; /** RTP sequence number **/
    /** bytes 8-11 **/
    unsigned int u32Ssrc; /**stream number is used here **/
} RTP_HEADER_S;

/***********************************************************
PT      encoding    media type  clock rate
        name                    (Hz)
_____________________________________________
24      unassigned  V
25      CelB        V           90,000
26      JPEG        V           90,000
27      unassigned  V
28      nv          V           90,000
29      unassigned  V
30      unassigned  V
31      H261        V           90,000
32      MPV         V           90,000
33      MP2T        AV          90,000
34      H263        V           90,000
35-71   unassigned  ?
72-76   reserved    N/A         N/A
77-95   unassigned  ?
96-127  dynamic     ?
dyn     H263-1998   V           90,000
Table 5: Payload types (PT) for video and combined
        encodings
***********************************************************/
enum PayloadType { H264 = 96, H265 = 97 };

// | magic number | channel number | embedded data length | data |
typedef struct _InterFrameHeader {
    char    magic_num{0x24};
    char    ch_num;
    u_short data_len;
} InterFrameHeader;

using DepayFunc = std::function<void(PayloadType, std::vector<u_char>&)>;
using RTCPFunc  = std::function<void(std::string rtcp_msg)>;
class RtpDepay {
private:
    //一个完整的rtp解包
    std::vector<u_char> one_rtp_pack_;
    // rtp源数据
    std::vector<u_char> rtp_data_;

    u_int32_t last_TimeStamp_{0};
    u_int32_t last_u32SeqNum_{0};

    DepayFunc depay_func_{nullptr};
    RTCPFunc  rtcp_func_{nullptr};

    RtcpMsg rtcp_msg_;

public:
    RtpDepay(/* args */){};
    ~RtpDepay(){};

    void SetDepayFunc(DepayFunc f) {
        depay_func_ = f;
    }

    void SetRTCPFunc(RTCPFunc f) {
        rtcp_func_ = f;
    }

    // rtp_head指向的数据长度要超过12字节
    bool PushRtpData(PayloadType pt, u_char* rtp_data, int len, bool close_flag);
    bool UnpackRtpHead(PayloadType pt, u_char* rtp_head, RTP_HEADER_S& rtphead);

    std::string GetRTCPRRMsg();
};
